package org.ricks.condition2;

import org.ricks.condition2.event.PlayerAwareEvent;
import org.ricks.ioc.utils.Logger;
import org.ricks.ioc.utils.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

public class ConditionManager {
    private static class SingletonHolder {
        private static final ConditionManager INSTANCE = new ConditionManager();
    }

    // 双层映射结构: playerId -> eventType -> conditions
    private final Map<String, Map<Class<? extends PlayerAwareEvent>, List<Condition>>> playerSubscriptions =
            new ConcurrentHashMap<>();

    public static ConditionManager ME() {
        return SingletonHolder.INSTANCE;
    }

    // 注册时自动按玩家ID分类
    public <E extends PlayerAwareEvent> void register(Condition condition) {
        String playerId = condition.getPlayerId();
        condition.getInterestedEventTypes().forEach(eventType -> {
            // 线程安全地构建嵌套映射
            Map<Class<? extends PlayerAwareEvent>, List<Condition>> eventMap =
                    playerSubscriptions.computeIfAbsent(playerId, k -> new ConcurrentHashMap<>());

            List<Condition> conditions =
                    eventMap.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>());

            if (!conditions.contains(condition)) {
                conditions.add(condition);
                condition.onRegistered();
            }
        });
    }

    // 注销时精准定位玩家的事件订阅
    public void unregister(Condition condition) {
        String playerId = condition.getPlayerId();
        Map<Class<? extends PlayerAwareEvent>, List<Condition>> eventMap =
                playerSubscriptions.get(playerId);

        if (eventMap != null) {
            condition.getInterestedEventTypes().forEach(eventType -> {
                List<Condition> conditions = eventMap.get(eventType);
                if (conditions != null) {
                    conditions.remove(condition);
                    // 自动清理空列表
                    if (conditions.isEmpty()) {
                        eventMap.remove(eventType);
                    }
                }
            });
            // 清理空玩家条目
            if (eventMap.isEmpty()) {
                playerSubscriptions.remove(playerId);
            }
            condition.onUnregistered();
        }
    }

    // 事件处理时直接定位目标玩家和事件类型
    public void onEvent(PlayerAwareEvent event) {
        String playerId = event.getPlayerId();
        Map<Class<? extends PlayerAwareEvent>, List<Condition>> eventMap = playerSubscriptions.get(playerId);

        if (eventMap == null) return;

        List<Condition> subscribers =
                eventMap.getOrDefault(event.getClass(), Collections.emptyList());

        subscribers.parallelStream().forEach(cond -> {
            try {
                if (!cond.isDone()) {
                    cond.emit(event);
                    if (cond.isDone()) {
                        unregister(cond);
                    }
                }
            } catch (Exception e) {
                Logger.error(StringUtils.format("Error handling event {} for condition {}", event, cond), e);
            }
        });
    }

    // 新增玩家维度清理接口
    public void cleanPlayerConditions(String playerId) {
        Map<Class<? extends PlayerAwareEvent>, List<Condition>> eventMap =
                playerSubscriptions.remove(playerId);

        if (eventMap != null) {
            eventMap.values().forEach(list ->
                    list.forEach(condition -> {
                        condition.onUnregistered();
                        condition.onCompleted();
                    })
            );
        }
    }

    public List<Condition> getPlayerConditions(String playerId) {
        return playerSubscriptions.getOrDefault(playerId, Map.of())
                .values().stream()
                .flatMap(List::stream)
                .collect(Collectors.toList());
    }
}
